package org.kth.dks.dks_marshal;

import java.io.IOException;
import java.util.Vector;

import org.kth.dks.DKSObject;
import org.kth.dks.dks_comm.DKSRef;
import org.kth.dks.dks_node.LookupType;

public class LookupResultMsg extends DKSMessage {
  private static String NAME= "LOOKUPRESULT";
  private DKSRef t;
  private LookupType type;
  private Vector stack;
  private String msgId;
  private DKSObject payload=null;  // invariant: only used if type==LookupType.DATA

  public String getName() { return NAME; }
  public DKSRef getT() { return t; }
  public LookupType getType() { return type; }
  public Vector getStack() { return stack; }
  public String getMsgId() { return msgId; }
  public DKSObject getPayload() { return payload; }

  public LookupResultMsg() {

  }

  public LookupResultMsg( DKSRef t, LookupType type, Vector stack, String msgId ) {

    this.t = t;
    this.type = type;
    this.stack = stack;
    this.msgId = msgId;
  }

  /* this version of the constructor has a DKSObject payload
      invariant: should only be used if type==LookupType.DATA, else above constructor should be used
   */
  public LookupResultMsg( DKSRef t, LookupType type, Vector vector, DKSObject payload, String msgId ) {

    this.t = t;
    this.type = type;
    this.stack = vector;
    this.msgId = msgId;
    this.payload = payload;
  }

  public void marshal() throws IOException {
    marshaler.addDKSRef( t, "target" );
    marshaler.addString( type.toString(), "type" );

    marshaler.addBool(payload == null ? false : true , "anypayload");
    if (payload != null) {
      marshaler.addDKSObject(payload, "payload");
    }

    marshaler.addBool(msgId == null ? false : true , "anyinsertid");
    if (msgId != null) {
      marshaler.addString(msgId, "insertid");
    }

    marshaler.addDKSRefArray( (DKSRef[]) stack.toArray( new DKSRef[0] ), "stack" );


  }

  public void unmarshal() throws IOException {
    t           = marshaler.remDKSRef("target");
    type        = LookupType.valueOf( marshaler.remString("type") );

    final boolean anyLoad = marshaler.remBool("anypayload");
    if (anyLoad) {
      payload = marshaler.remDKSObject("payload");
    }

    final boolean anyId = marshaler.remBool("anyinsertid");
    if (anyId) {
      msgId = marshaler.remString("insertid");
    }

    stack = new Vector( marshaler.remDKSRefArray("stack") );
  }
}
